package org.willthink.controller.fileupload;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import org.willthink.common.PagingProcessUtil;
import org.willthink.common.PropertyPlaceholder;
import org.willthink.service.fileupload.FileUploadService;
import org.willthink.vo.common.PagingValuesVo;
import org.willthink.vo.fileupload.FileUploadInfoVo;

@Controller
public class FileUploadController {
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private PropertyPlaceholder propertyPlaceholder;
	
	@Autowired
	private PagingProcessUtil pagingProcessUtil;
	
	private FileUploadService fileUploadServiceImpl; 
	
	public void setFileUploadServiceImpl(FileUploadService fileUploadServiceImpl) {
		this.fileUploadServiceImpl = fileUploadServiceImpl;
	}

	// 테스트
	@RequestMapping(value="/fileupload/fileAddJsp.think")
	public ModelAndView fileAddJsp() {
		logger.debug("FileUploadController fileAddJsp()");
		ModelAndView mv = new ModelAndView();
		mv.setViewName("fileupload/file_Add1");
		return mv;
	}
	
	// 파일 첨부한거 디비 입력
	@RequestMapping(value="/fileupload/fileAdd.think", method=RequestMethod.POST)
	public ModelAndView fileAdd(MultipartHttpServletRequest request) {
		
		logger.debug("FileUploadController fileAdd()");
		// http://localhost:8080/WillThink/fileupload/fileAddJsp.think
		Map<String, MultipartFile> uploadFilesMap = request.getFileMap(); 
		logger.debug("fileAdd() uploadFilesMap : {}", uploadFilesMap);
		logger.debug("fileAdd() uploadFilesMap 업로드한 파일 갯수 : {}", uploadFilesMap.size());
		/*
		try {
			if(uploadFilesMap != null) {	
				
				logger.debug("fileAdd() propertyPlaceholder : {}", propertyPlaceholder);
				logger.debug("fileAdd() propertyPlaceholder.getMergedProperties() : {}", propertyPlaceholder.getMergedProperties());
				logger.debug("fileAdd() property file path : {}", propertyPlaceholder.getMergedProperties().getProperty("test.save.path")); // test.save.path, real.save.path
				String uploadFileSavePath = propertyPlaceholder.getMergedProperties().getProperty("test.save.path"); // test.save.path, test.save.path
				
				Set<Entry<String, MultipartFile>> set = uploadFilesMap.entrySet();
				Iterator<Entry<String, MultipartFile>> iterator = set.iterator();
				
				MultipartFile uploadFile = null;
				
				long systemTime =System.currentTimeMillis();
				
				while (iterator.hasNext()) {
					
					Map.Entry<String, MultipartFile> uploadFileEntry = iterator.next();
					
					logger.debug("fileAdd() uploadFile key : {}", uploadFileEntry.getKey());
					logger.debug("fileAdd() uploadFile value : {}", uploadFileEntry.getValue());
					
					uploadFile = uploadFilesMap.get(uploadFileEntry.getKey());
					
					if(!uploadFile.getOriginalFilename().isEmpty()) {
						
						logger.debug("fileAdd() fileUploadServiceImpl : {}", fileUploadServiceImpl);
						long tempSystemTime = systemTime++;
						String modifyFileName = tempSystemTime + "_" + uploadFile.getOriginalFilename();
						logger.debug("fileAdd() modifyFileName : {}", modifyFileName);
						String realFileName = uploadFile.getOriginalFilename();
						logger.debug("fileAdd() realFileName : {}", realFileName);
						
						fileUploadServiceImpl.uploadFilesDbInsert(
								new FileUploadInfoVo(tempSystemTime, // 시스템시간 <= check
										realFileName + "#" + modifyFileName , // 실제파일이름//변경파일명
										uploadFile.getSize(), // 파일크기
										null, // filePath          <= check
										"DATA_ROOM", // boardType <= check
										0, // contentNo            <= check
										null, // regdate 
										"n")); // deleteFlag
						
						logger.debug("fileAdd() uploadFile.getOriginalFilename() : {}", uploadFile.getOriginalFilename());
						File destFile = new File(uploadFileSavePath + "/" + modifyFileName);
						logger.debug("fileAdd() tempFile : {}", destFile);
						
						uploadFile.transferTo(destFile); // 파일저장경로에 임시파일 만든다음 파일복사
					}
				
				}
				
				
			} else {
				
				return new ModelAndView(new RedirectView("../fileupload/fileUploadList.think?page=1"));
				
			}
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		*/
		return new ModelAndView(new RedirectView("../fileupload/fileUploadList.think?page=1")); 
	
	}
	
	// 파일 전체 리스트
	@RequestMapping(value="/fileupload/fileUploadList.think")
	public ModelAndView fileList(HttpServletRequest request, HttpServletResponse response) {
		// http://localhost:8080/WillThink/fileupload/fileUploadList.think?page=1
		logger.debug("FileUploadController file_List()");
		ModelAndView mv = new ModelAndView();
		
		ArrayList<FileUploadInfoVo> uploadFileInfoList = null;
		
		String strPageNumber = request.getParameter("page");
		
		int selectUploadFileAllRowCnt = fileUploadServiceImpl.getUploadFileAllRow();
		logger.debug("selectUploadFileAllRowCnt :{}", selectUploadFileAllRowCnt);
		logger.debug("fileList() pagingProcessUtil : {}", pagingProcessUtil);
		PagingValuesVo pagingValuesVo = pagingProcessUtil.getPagingProcess(strPageNumber, selectUploadFileAllRowCnt);
		logger.debug("fileList() pagingValuesVo : {}", pagingValuesVo);
		
		uploadFileInfoList = fileUploadServiceImpl.getUploadFileList(pagingValuesVo.getFirstRow(), pagingValuesVo.getEndRow());
		logger.debug("fileList() uploadFileInfolist : {}", uploadFileInfoList);
		
		Map model = new HashMap(); 
		model.put("fileList", uploadFileInfoList);
		model.put("pagingProcess", pagingValuesVo);
		model.put("path1", "fileUploadList.think?page=" + (pagingValuesVo.getFirstPageNumber()-1));
		model.put("path2", "fileUploadList.think?page=");
		model.put("path3", "fileUploadList.think?page=" + (pagingValuesVo.getEndPageNumber()+1));

		mv.setViewName("fileupload/file_List");
		mv.addAllObjects(model);
		return mv;
	}
	
	// 파일 다운로드
	@RequestMapping(value="/filedownload/filedownload.think")
	public ModelAndView fileDownload(/*@RequestParam("fileName") String fileName, */
			HttpServletRequest request, HttpServletResponse response) {
		// http://localhost:8080/WillThink/filedownload/filedownload.think?fileName=1317567965892_새 텍스트 문서.txt
		String uploadFileSavePath = null;
		String tempFileName = null;
		String realFileName = null;
		try {
			
			tempFileName = request.getParameter("tempFileName");
			realFileName = request.getParameter("realFileName");
			
			logger.debug("fileDownload() tempFileName : {}", tempFileName);
			logger.debug("fileDownload() realFileName : {}", realFileName);
			
			uploadFileSavePath = propertyPlaceholder.getMergedProperties().getProperty("test.save.path"); // test.save.path
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		File downloadFile = new File(uploadFileSavePath + "/" + tempFileName.trim());
		logger.debug("fileDownload() downloadFile : {}", downloadFile);
		
		Map model = new HashMap(); 
		model.put("downloadFile", downloadFile);
		model.put("realFileName", realFileName);
	
		return new ModelAndView("download", model);
	}
	
	// 파일 검색
	@RequestMapping(value="/filesearch/fileSearch.think")
	public ModelAndView fileSearch(@RequestParam("searchText") String searchText, HttpServletRequest request) {
		
		logger.debug("=======================> ModelAndView fileSearch");
		
		String searchFileName = searchText.trim();
		try {
			searchFileName = new String(searchFileName.getBytes("8859_1"), "UTF-8");
			logger.debug("searchFileName : {}", searchFileName);
		} catch (UnsupportedEncodingException e) {
			
			e.printStackTrace();
		}
	
		ArrayList<FileUploadInfoVo> searchFileInfoList = null;
		String strPageNumber = request.getParameter("page");
		
		searchFileInfoList = fileUploadServiceImpl.getSearchFileList(searchFileName);
		logger.debug("searchFileInfoList : {}", searchFileInfoList);
		
		int searchFileAllRowCnt = searchFileInfoList.size();
		logger.debug("searchFileAllRowCnt : {}", searchFileAllRowCnt);
		logger.debug("fileList() pagingProcessUtil : {}", pagingProcessUtil);
		PagingValuesVo pagingValuesVo = pagingProcessUtil.getPagingProcess(strPageNumber, searchFileAllRowCnt);
		logger.debug("fileList() pagingValuesVo : {}", pagingValuesVo);
		
		ArrayList<FileUploadInfoVo> tempSearchFileInfoList = new ArrayList<FileUploadInfoVo>();
		
		for (int i = pagingValuesVo.getFirstRow()-1; i < searchFileInfoList.size(); i++) {
			if(i < pagingValuesVo.getEndRow()) {
				tempSearchFileInfoList.add(searchFileInfoList.get(i));
			}
		}
		
		ModelAndView mv = new ModelAndView();
		Map model = new HashMap(); 
		model.put("fileList", tempSearchFileInfoList);
		model.put("pagingProcess", pagingValuesVo);
		model.put("path1", "fileSearch.think?page=" + (pagingValuesVo.getFirstPageNumber()-1) + "&searchText=" + searchFileName);
		model.put("path2", "fileSearch.think?searchText=" + searchFileName + "&page=");
		model.put("path3", "fileSearch.think?page=" + (pagingValuesVo.getEndPageNumber()+1) + "&searchText=" + searchFileName);
		
		mv.setViewName("fileupload/file_List");
		mv.addAllObjects(model);
		
		return mv;
	}
	
	// 파일삭제
	@RequestMapping(value="/filedelete/filedelete.think")
	public ModelAndView fileDelete(@RequestParam("no") String no) {
		
		logger.debug("deleteNo : {}", no);
		// 디비에서 해당파일 변경파일명 검색
		String deleteFileName = fileUploadServiceImpl.getDeleteFileName(Integer.parseInt(no));
		String[] arrDeleteFileName = deleteFileName.split("#");
		logger.debug("deleteFileName : {}", deleteFileName);
		try {
			String realPath = propertyPlaceholder.getMergedProperties().getProperty("test.save.path"); // test.save.path, real.save.path
			File deleteFile = new File(realPath + "/" + arrDeleteFileName[1]);
			boolean deleteFlag = deleteFile.delete();
			logger.debug("파일삭제여부 : {}", deleteFlag);
			fileUploadServiceImpl.deleteFile(Integer.parseInt(no)); // 디비에서 row삭제
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return new ModelAndView(new RedirectView("../fileupload/fileUploadList.think?page=1"));
	}
	
	
}
